﻿using System.Configuration;
using System.Security;
using Autofac;
using AutofacContrib.DynamicProxy2;
using Castle.DynamicProxy;
using OS.Infrastructure.Common;
using OS.Infrastructure.Domain;
using OS.Infrastructure.Domain.UnitOfWork;
using OS.Infrastructure.NHibernate;
using OS.Infrastructure.NHibernate.Linq;
using OS.Infrastructure.NHibernate.Repositories;
using OS.Infrastructure.NHibernate.UnitOfWorkAware;
using TaskKernel.Domain.Interface;
using TaskKernel.Domain.Nhibernate;
using TaskKernel.Domain.Nhibernate.NHibernateLayer;
using TaskKernel.Domain.Services.Action;
using TaskKernel.Domain.Services.Mail;
using TaskKernel.Infrastructure;

namespace TaskKernel.BootStrapper
{
    public static class TaskKernelBootStrapper
    {
        private static ContainerBuilder _builder;

        public static void RunWebServiceApp()
        {
            _builder = new ContainerBuilder();
            _builder.RegisterModule(new WebServiceAppAutoFacModule());
            IoC.Init(_builder.Build());
        }

        public static void RunConsoleApp()
        {
            _builder = new ContainerBuilder();
            _builder.RegisterModule(new ConsoleAppAutoFacModule());
            IoC.Init(_builder.Build());
        }

        public static void Run(Module module)
        {
            _builder = new ContainerBuilder();
            _builder.RegisterModule(module);
            IoC.Init(_builder.Build());
        }
    }

    public class ConsoleAppAutoFacModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            builder.Register(x => new SmtpSender(ConfigurationManager.AppSettings["smtpServer"])).As<IMessageSender>();
            builder.Register(x => new NHInitializer(ConfigurationManager.AppSettings["connectionString"])).As<INHibernateInitializer>();
            builder.Register(x => new FileManager(ConfigurationManager.AppSettings["fileStorage"])).AsSelf();
            builder.RegisterType<SessionProvider>().As<ISessionProvider>();
            builder.RegisterType<NHibernateLinqProvider>().As<ILinqProvider>();
            builder.RegisterType<NHibernateUnitOfWorkFactory>().As<IUnitOfWorkFactory>();
            builder.RegisterType<QueryTask>().As<IQueryTask>();
            builder.RegisterType<QueryFile>().As<IQueryFile>();
            builder.RegisterType<TaskAction>().As<ITaskAction>().EnableInterfaceInterceptors().InterceptedBy(typeof (SecurityInterceptor));
            builder.RegisterType<SecurityInterceptor>();
            builder.RegisterType<MessageService>().As<IMessageService>();
            builder.RegisterGeneric(typeof (BaseRepository<>)).As(typeof (ICommandRepository<>));
        }
    }

    public class WebServiceAppAutoFacModule : ConsoleAppAutoFacModule
    {
        protected override void Load(ContainerBuilder builder)
        {
            base.Load(builder);
            builder.RegisterType<QueryAccount>().As<IQueryAccount>();
            builder.RegisterType<QueryDepartment>().As<IQueryDepartment>();
            builder.RegisterType<QueryProposalForm>().As<IQueryProposalForm>();
            builder.RegisterType<DepartmentService>().As<IDepartmentService>();
        }
    }

    internal class SecurityInterceptor : IInterceptor
    {
        #region IInterceptor Members

        public void Intercept(IInvocation invocation)
        {
            try{
                invocation.Proceed();
            }
            catch (SecurityException){
                invocation.ReturnValue = false;
            }
        }

        #endregion
    }
}